﻿// HexEditorView.cpp: CHexEditorView 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "HexEditor.h"
#endif

#include "HexEditorDoc.h"
#include "HexEditorView.h"
#include "CEditSheet.h"
#include "CEditPage.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CEditSheet* g_pEditSheet;
bool g_bInit = false;

// CHexEditorView

IMPLEMENT_DYNCREATE(CHexEditorView, CView)

BEGIN_MESSAGE_MAP(CHexEditorView, CView)
	ON_COMMAND(ID_FILE_OPEN, &CHexEditorView::OnFileOpen)
	ON_COMMAND(ID_FILE_SAVE, &CHexEditorView::OnFileSave)
	ON_COMMAND(ID_FIND, &CHexEditorView::OnFind)
	ON_COMMAND(ID_FIND_NEXT, &CHexEditorView::OnFindNext)
	ON_COMMAND(ID_JUMP, &CHexEditorView::OnJump)
	ON_COMMAND(ID_FILL, &CHexEditorView::OnFill)
	ON_COMMAND(ID_COPY, &CHexEditorView::OnEditCopy)
	ON_COMMAND(ID_PASTE, &CHexEditorView::OnEditPaste)
	ON_COMMAND(ID_SAVE_TO, &CHexEditorView::OnSaveAs)
	ON_COMMAND(ID_ADD, &CHexEditorView::OnAddOneColumns)
	ON_COMMAND(ID_SUB, &CHexEditorView::OnSubOneColumns)
	ON_COMMAND(ID_CLOSE, &CHexEditorView::OnFileClose)
	ON_COMMAND(ID_RELOAD, &CHexEditorView::OnReload)
	ON_WM_SIZE()
END_MESSAGE_MAP()

// CHexEditorView 构造/析构

CHexEditorView::CHexEditorView() noexcept {
	// TODO: 在此处添加构造代码
}

CHexEditorView::~CHexEditorView() {
}

BOOL CHexEditorView::PreCreateWindow(CREATESTRUCT& cs) {
	return CView::PreCreateWindow(cs);
}

void CHexEditorView::OnFileOpen() {
	CPageInfo pageInfo;
	//打开文件夹，选择文件
	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("All Files (*.*)|*.*||"));
	if (g_bInit) {
		if (dlg.DoModal() == IDOK) {
			CString strPath = dlg.GetPathName();
			pageInfo.m_strFilePath = strPath;
			CString filename = dlg.GetFileName();
			pageInfo.m_strFileName = filename;
			//打开文件
			CFile file;
			if (file.Open(strPath, CFile::modeRead)) {
				//获取文件大小
				DWORD dwSize = (DWORD)file.GetLength();
				BYTE* pBuf = new BYTE[dwSize];
				//读取文件内容
				file.Read(pBuf, dwSize);
				file.Close();
				//创建一个新的编辑页
				CEditPage* page = new CEditPage();
				pageInfo.m_pPage = page;
				//设置标题为文件名
				page->m_psp.pszTitle = filename;
				page->m_psp.dwFlags |= PSP_USETITLE;
				g_pEditSheet->m_pages.push_back(pageInfo);
				g_pEditSheet->AddPage(page);
				g_pEditSheet->SetActivePage(page);
				//设置数据
				page->m_HexEdit.SetAddressSize(8, false);
				page->m_HexEdit.SetShowAddress(true, false);
				page->m_HexEdit.SetBytesPerRow(16, false, false);
				page->m_HexEdit.SetData(pBuf, dwSize);
				page->m_HexEdit.SetShowAscii(true);
				//page->m_HexEdit.SetAsciiCol(16777215, 0);
				//page->m_HexEdit.SetAdrCol(16777215, 0);
				page->m_HexEdit.SetShowColumnNum(true);
				delete[] pBuf;
				pBuf = NULL;
			}
		}
		return;
	}
	if (dlg.DoModal() == IDOK) {
		g_pEditSheet = new CEditSheet(_T("Hex Editor"), this);
		g_bInit = true;
		CString strPath = dlg.GetPathName();
		pageInfo.m_strFilePath = strPath;
		CString filename = dlg.GetFileName();
		pageInfo.m_strFileName = filename;
		//打开文件
		CFile file;
		if (file.Open(strPath, CFile::modeRead)) {
			//获取文件大小
			DWORD dwSize = (DWORD)file.GetLength();
			BYTE* pBuf = new BYTE[dwSize];
			//读取文件内容
			file.Read(pBuf, dwSize);
			file.Close();
			//创建一个新的编辑页
			CEditPage* page = new CEditPage();
			pageInfo.m_pPage = page;
			//设置标题为文件名
			page->m_psp.pszTitle = filename;
			page->m_psp.dwFlags |= PSP_USETITLE;
			g_pEditSheet->m_pages.push_back(pageInfo);
			g_pEditSheet->AddPage(page);
			g_pEditSheet->Create(this, WS_CHILD | WS_VISIBLE, 0);
			CRect rectClient;
			GetClientRect(&rectClient);
			g_pEditSheet->SetWindowPos(nullptr, rectClient.left, rectClient.top,
				rectClient.Width(), rectClient.Height(), SWP_NOZORDER);
			//设置数据
			page->m_HexEdit.SetAddressSize(8, false);
			page->m_HexEdit.SetShowAddress(true, false);
			page->m_HexEdit.SetBytesPerRow(16, false, false);
			page->m_HexEdit.SetData(pBuf, dwSize);
			page->m_HexEdit.SetShowAscii(true);
			//page->m_HexEdit.SetAsciiCol(16777215, 0);
			//page->m_HexEdit.SetAdrCol(16777215, 0);
			page->m_HexEdit.SetShowColumnNum(true);
			delete[] pBuf;
			pBuf = NULL;
		}
	}
}

void CHexEditorView::OnFileSave() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			int index = g_pEditSheet->GetActiveIndex();
			CPageInfo pageInfo = g_pEditSheet->m_pages[index];
			CFile file;
			if (file.Open(pageInfo.m_strFilePath, CFile::modeWrite | CFile::modeCreate)) {
				//获取数据大小
				DWORD dwSize = page->m_HexEdit.GetDataSize();
				BYTE* pBuf = new BYTE[dwSize];
				//获取数据
				page->m_HexEdit.GetData(pBuf, dwSize);
				//写入文件
				file.Write(pBuf, dwSize);
				file.Close();
				delete[] pBuf;
				pBuf = NULL;
			}
		}
	}
	MessageBox(_T("已保存!"));
}

void CHexEditorView::OnSaveAs() {
	//另存为
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			int index = g_pEditSheet->GetActiveIndex();
			CPageInfo pageInfo = g_pEditSheet->m_pages[index];
			CString filename = pageInfo.m_strFileName;
			CString fileExtension = filename.Mid(filename.ReverseFind('.') + 1);
			CString fileFilter;
			fileFilter.Format(_T("%s Files (*.%s)|*.%s|All Files (*.*)|*.*||"), fileExtension, fileExtension, fileExtension);

			// 初始化文件对话框
			CFileDialog dlg(FALSE, fileExtension, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, fileFilter);
			if (dlg.DoModal() == IDOK) {
				CString strPath = dlg.GetPathName();
				pageInfo.m_strFilePath = strPath;
				CString filename = dlg.GetFileName();
				//打开文件
				CFile file;
				if (file.Open(strPath, CFile::modeWrite | CFile::modeCreate)) {
					//获取数据大小
					DWORD dwSize = page->m_HexEdit.GetDataSize();
					BYTE* pBuf = new BYTE[dwSize];
					//获取数据
					page->m_HexEdit.GetData(pBuf, dwSize);
					//写入文件
					file.Write(pBuf, dwSize);
					file.Close();
					delete[] pBuf;
					pBuf = NULL;
				}
			}
		}
	}
}

void CHexEditorView::OnEditCopy() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			page->m_HexEdit.OnEditCopy();
		}
	}
}

void CHexEditorView::OnEditPaste() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			page->m_HexEdit.OnEditPaste();
		}
	}
}

void CHexEditorView::OnFind() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			page->m_HexEdit.OnEditFind();
		}
	}
}

void CHexEditorView::OnFindNext() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			page->m_HexEdit.OnEditFindNext();
		}
	}
}

void CHexEditorView::OnJump() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			page->m_HexEdit.OnGoto();
		}
	}
}

void CHexEditorView::OnFill() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			page->m_HexEdit.OnEditFill();
		}
	}
}

void CHexEditorView::OnAddOneColumns() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			page->m_HexEdit.AddOneColumns();
		}
	}
}

void CHexEditorView::OnSubOneColumns() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			page->m_HexEdit.DecOneColumns();
		}
	}
}

void CHexEditorView::OnFileClose() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			int index = g_pEditSheet->GetActiveIndex();
			g_pEditSheet->m_pages.erase(g_pEditSheet->m_pages.begin() + index);
			g_pEditSheet->RemovePage(index);
			delete page;
		}
	}
	if (g_pEditSheet->m_pages.size() == 0) {
		delete g_pEditSheet;
		g_pEditSheet = NULL;
		g_bInit = false;
	}
}

void CHexEditorView::OnReload() {
	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page) {
			int index = g_pEditSheet->GetActiveIndex();
			CPageInfo pageInfo = g_pEditSheet->m_pages[index];
			CFile file;
			if (file.Open(pageInfo.m_strFilePath, CFile::modeRead)) {
				//获取文件大小
				DWORD dwSize = (DWORD)file.GetLength();
				BYTE* pBuf = new BYTE[dwSize];
				//读取文件内容
				file.Read(pBuf, dwSize);
				file.Close();
				//设置数据
				page->m_HexEdit.SetData(pBuf, dwSize);
				delete[] pBuf;
				pBuf = NULL;
			}
		}
	}
}

void CHexEditorView::OnSize(UINT nType, int cx, int cy) {
	CView::OnSize(nType, cx, cy);
	// 调整属性表的大小
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		g_pEditSheet->SetWindowPos(NULL, 0, 0, cx, cy, SWP_NOZORDER | SWP_NOACTIVATE);
	}
}

// CHexEditorView 绘图

void CHexEditorView::OnDraw(CDC* /*pDC*/) {
	CHexEditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
}

// CHexEditorView 诊断

#ifdef _DEBUG
void CHexEditorView::AssertValid() const {
	CView::AssertValid();
}

void CHexEditorView::Dump(CDumpContext& dc) const {
	CView::Dump(dc);
}

CHexEditorDoc* CHexEditorView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHexEditorDoc)));
	return (CHexEditorDoc*)m_pDocument;
}
#endif //_DEBUG

// CHexEditorView 消息处理程序